package pl.szpadel.android.gadu;

import java.util.HashSet;

import pl.szpadel.android.gadu.packets.ReceivedPacket;

import android.app.Activity;
import android.content.Context;

/// The Application
/// Singleton containing all app components
public class App {
	
	/////////////////////////////////
	// singleton
	
	/// singpleton instance
	static private App mInstance = null;
	
	/// global context
	private Context mContext;
	
	
	/// Creates instance, if not created yet
	static public void createInstance(Context ctx) {
		if (mInstance == null) {
			mInstance = new App(ctx);
		}
	}
	
	/// Singleton instance getter
	static public synchronized App getInstance() {
		return mInstance;
	}
	
	ConnectionState mConnectionState = ConnectionState.Disconnected(-1);
	
	////////////////////////////////
	// Components
	
	private Config mConfig = new Config();
	
	private ContactInfoManager mContactInfoManager = null;
	private ContactListActivity mContactListActivity = null;
	private LogonActivity mLogonActivity = null;
	private CommunicationService mCommunicationService = null;
	private UserNotification mUserNotification = null;
	private ChatManager mChatManager = null;
	private ChatActivity mChatActivity = null;

	
	public ContactInfoManager getContactInfoManager() { return mContactInfoManager; }
	
	public UserNotification getUserNotification() { return mUserNotification; }
	
	public ChatManager getChatManager() { return mChatManager; }
	
	public void setContactListActivity(ContactListActivity contactListActivity) {
		mContactListActivity = contactListActivity;
	}

	public void setCommunicationService(CommunicationService service) {
		mCommunicationService = service;
	}

	public CommunicationService getCommunicationService() {
		return mCommunicationService;
	}

	public void setLogonActivity(LogonActivity logonActivity) {
		mLogonActivity = logonActivity;
	}

	public LogonActivity getLogonActivity() {
		return mLogonActivity;
	}

	public ContactListActivity getContactListActivity() {
		return mContactListActivity;
	}
	
	public Config getConfig() {
		return mConfig;
	}
	
	///////////////////////////////////////////////////
	// components
	HashSet<IAppComponent> mComponents = new HashSet<IAppComponent>();
	
	/// Adds app component to app
	void registerAppComponent(IAppComponent component) {
		mComponents.add(component);
	}
	
	/// Removes app component
	void deregisterAppComponent(IAppComponent component) {
		mComponents.remove(component);
	}
	
	/// Broadcast incoming packet among components
	void broadcastPacket(ReceivedPacket packet) {
		for (IAppComponent c : mComponents) {
			c.onPacket(packet);
		}
	}
	
	/// Broadcast connection state change among components
	void broadcastConnectionState(ConnectionState state) {
		mConnectionState = state;
		
		for (IAppComponent c : mComponents) {
			c.onConnectionStateChanged(state);
		}
	}
	
	/// Broadcast status change among components
	void broadcastStatusChange(Status status) {
		for (IAppComponent c : mComponents) {
			c.onStatusChanged(status);
		}
	}
	
	/// Broadcast config change among components
	void broadcastConfigChange() {
		for (IAppComponent c : mComponents) {
			c.onConfigChanged();
		}
	}
	
	/// returns GG client version reported to the server
	public String getGGClientVersion() {
		return mContext.getText(R.string.reported_client_version).toString();
	}
	


	/// C-tor
	private App(Context ctx) {
		mContext = ctx;
		mContactInfoManager = new ContactInfoManager(mContext);
		mUserNotification = new UserNotification(mContext);
		mChatManager = new ChatManager(mContext);
		
		mConfig.read(ctx);
		
		registerAppComponent(mContactInfoManager);
		registerAppComponent(mUserNotification);
		registerAppComponent(mChatManager);
	}

	///////////////////////////////////
	// Other method
	
	/// Provides global context
	public Context getContext() {
		return mContext;
	}
	
	/// Provides 'main activity' which can be used as access to UI thread and other services
	public Activity getActivity() {
		return mContactListActivity; // this could be smarter
	}
	
	/// Returns last connection state
	ConnectionState getConnectionState() {
		return mConnectionState;
	}

	public void setChatActivity(ChatActivity chatActivity) {
		mChatActivity = chatActivity;
	}

	public ChatActivity getChatActivity() {
		return mChatActivity;
	}

	
}
